// 引入必要的命名空间
using UniversalAdmin.Application.DTOs; // 引入数据传输对象定义
using UniversalAdmin.Domain.Entities; // 引入领域实体定义
using UniversalAdmin.Domain.Repositories; // 引入仓储接口定义

// 定义服务层的命名空间
namespace UniversalAdmin.Application.Services;

// 实现文章分类服务接口
public class ArticleCategoryService : IArticleCategoryService
{
    // 注入文章分类仓储接口
    private readonly IArticleCategoryRepository _categoryRepository;

    // 构造函数，依赖注入IArticleCategoryRepository
    public ArticleCategoryService(IArticleCategoryRepository categoryRepository)
    {
        _categoryRepository = categoryRepository;
    }

    // 获取所有文章分类
    public async Task<IEnumerable<ArticleCategoryDto>> GetAllCategoriesAsync()
    {
        // 调用仓储层获取所有分类
        var categories = await _categoryRepository.GetAllAsync();
        // 将分类实体映射为DTO并返回
        return categories.Select(MapToDto);
    }

    // 获取分类树形结构
    public async Task<IEnumerable<ArticleCategoryDto>> GetCategoryTreeAsync()
    {
        // 调用仓储层获取所有分类
        var allCategories = await _categoryRepository.GetAllAsync();
        // 将分类实体映射为DTO并转换为列表
        var categoryDtos = allCategories.Select(MapToDto).ToList();
        
        // 构建树形结构
        // 获取所有根分类（ParentId为null的分类）
        var rootCategories = categoryDtos.Where(c => c.ParentId == null).OrderBy(c => c.SortOrder).ToList();
        // 递归构建每个根分类的子分类树
        foreach (var rootCategory in rootCategories)
        {
            BuildCategoryTree(rootCategory, categoryDtos);
        }
        
        // 返回树形结构的根分类列表
        return rootCategories;
    }

    // 根据ID获取单个分类
    public async Task<ArticleCategoryDto?> GetCategoryByIdAsync(Guid id)
    {
        // 调用仓储层根据ID获取分类
        var category = await _categoryRepository.GetByIdAsync(id);
        // 如果分类存在，映射为DTO并返回；否则返回null
        return category != null ? MapToDto(category) : null;
    }

    // 创建新分类
    public async Task<ArticleCategoryDto> CreateCategoryAsync(CreateArticleCategoryDto dto)
    {
        // 根据DTO创建分类实体
        var category = new ArticleCategory
        {
            Name = dto.Name,
            Description = dto.Description,
            ParentId = dto.ParentId,
            SortOrder = dto.SortOrder,
            CreatedAt = DateTime.UtcNow
        };

        // 调用仓储层添加分类
        var createdCategory = await _categoryRepository.AddAsync(category);
        // 将新创建的分类映射为DTO并返回
        return MapToDto(createdCategory);
    }

    // 更新分类
    public async Task<ArticleCategoryDto?> UpdateCategoryAsync(Guid id, UpdateArticleCategoryDto dto)
    {
        // 调用仓储层根据ID获取分类
        var category = await _categoryRepository.GetByIdAsync(id);
        // 如果分类不存在，返回null
        if (category == null) return null;

        // 更新分类属性
        category.Name = dto.Name;
        category.Description = dto.Description;
        category.ParentId = dto.ParentId;
        category.SortOrder = dto.SortOrder;
        category.UpdatedAt = DateTime.UtcNow;

        // 调用仓储层更新分类
        await _categoryRepository.UpdateAsync(category);
        // 将更新后的分类映射为DTO并返回
        return MapToDto(category);
    }

    // 删除分类
    public async Task<bool> DeleteCategoryAsync(Guid id)
    {
        // 调用仓储层根据ID获取分类
        var category = await _categoryRepository.GetByIdAsync(id);
        // 如果分类不存在，返回false
        if (category == null) return false;

        // 检查是否有子分类
        var hasChildren = await _categoryRepository.HasChildrenAsync(id);
        if (hasChildren)
        {
            throw new InvalidOperationException("无法删除有子分类的分类项");
        }

        // 检查是否有文章
        var hasArticles = await _categoryRepository.HasArticlesAsync(id);
        if (hasArticles)
        {
            throw new InvalidOperationException("无法删除有文章的分类项");
        }

        // 调用仓储层删除分类
        await _categoryRepository.DeleteAsync(category);
        // 返回删除成功标志
        return true;
    }

    // 递归构建分类树
    private void BuildCategoryTree(ArticleCategoryDto parent, List<ArticleCategoryDto> allCategories)
    {
        // 设置当前分类的子分类列表
        parent.Children = allCategories
            .Where(c => c.ParentId == parent.Id)
            .OrderBy(c => c.SortOrder)
            .ToList();
        
        // 递归构建每个子分类的子树
        foreach (var child in parent.Children)
        {
            BuildCategoryTree(child, allCategories);
        }
    }

    // 将分类实体映射为DTO
    private static ArticleCategoryDto MapToDto(ArticleCategory category)
    {
        return new ArticleCategoryDto
        {
            Id = category.Id,
            Name = category.Name,
            Description = category.Description,
            ParentId = category.ParentId,
            SortOrder = category.SortOrder,
            CreatedAt = category.CreatedAt,
            UpdatedAt = category.UpdatedAt
        };
    }
} 